﻿using Microsoft.IdentityModel.Tokens;
using System;
using System.Linq;
using static CoreLims.Models.CoreLims.INV;

namespace CoreLims.Models.CoreLims
{
    public sealed partial class INV
    {
        public static Material Material;
        public static Inventory Inventory;
        public static UseInventory UseInventory;
        public static InventoryEx InventoryEx;

        /// <summary>
        /// 库存单状态  核销：对于入库单来讲，可领用数量减少为0，代表该库存单的物品已经全部被领用。
        /// 对于出库单来说  核销：是关联的试剂，在每次配置后由系统自动或手工扣除为0时所产生的状态，代表该出库单物品被消耗干净。
        /// 入库单为锁定状态时将不能再产生新的出库单。出库单为锁定状态时将不能领用(严格管控的物料出库后将是锁定状态，直到审批流程完成才能解除锁定状态)。
        /// 已合并：两种库存单都可以合并，合并时将三个数值全部叠加到目标记录（暂为使用）
        /// </summary>
        public enum InventoryStatus { 正常, 核销, 锁定, 已合并 };
    }

    /// <summary>
    /// 物料
    /// </summary>
    public partial class Material
    {
        public Material()
        {
            this.IsEnable = true;
            this.IsReview = false;
        }

        /// <summary>
        /// 物料代码
        /// </summary>
        public string Code { get; set; }

        /// <summary>
        /// 物料名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 一级分类
        /// </summary>
        public string Type1 { get; set; }

        /// <summary>
        /// 二级分类
        /// </summary>
        public string Type2 { get; set; }

        /// <summary>
        /// 该备件关联的设备类型
        /// 如果是设备备件，则必须指明其关联的 设备类型
        /// 设置设备类型，则同类型设备备件中都会出现该物料。如果不设置类型，只设置设备ID，则该物料只会出现在特定设备的备件信息中。
        /// </summary>
        public string EquipmentType { get; set; }

        /// <summary>
        /// 该备件关联的设备ID
        /// </summary>
        public string EquipmentId { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        public string Note { get; set; }

        /// <summary>
        /// 高限，针对入库单 AvailableQuantity 可领用数量 的高限。
        /// </summary>
        public int? HighLimit { get; set; }

        /// <summary>
        /// 低限，针对入库单 AvailableQuantity 可领用数量 的低限。
        /// </summary>
        public int? LowLimit { get; set; }

        /// <summary>
        /// 提醒组ID
        /// </summary>
        public string RemindGroupId { get; set; }

        /// <summary>
        /// 提醒组
        /// </summary>
        public string RemindGroup { get; set; }

        /// <summary>
        /// 提醒人ID
        /// </summary>
        public string RemindPersonId { get; set; }

        /// <summary>
        /// 提醒人
        /// </summary>
        public string RemindPerson { get; set; }

        /// <summary>
        /// 启用/停用
        /// </summary>
        public bool IsEnable { get; set; }

        /// <summary>
        /// 是否属于严格管控物料，该属性在生成入库单时被带入入库单中，严格管控的物料在出库时，会启动审核流程。
        /// </summary>
        public bool IsReview { get; set; }

        public Material Copy(Material other)
        {
            this.Name = other.Name;
            this.Type1 = other.Type1;
            this.Type2 = other.Type2;
            this.EquipmentType = other.EquipmentType;
            this.EquipmentId = other.EquipmentId;
            this.Note = other.Note;
            this.LowLimit = other.LowLimit;
            this.HighLimit = other.HighLimit;
            return this;
        }
    }

    /// <summary>
    /// 库存单
    /// </summary>
    public partial class Inventory : IWorkFlow<Inventory>
    {
        /// <summary>
        /// 入库单
        /// </summary>
        public Inventory() { 
            this.Id = Guid.NewGuid().ToString();
            this.InDate = DateTime.Now;
            this.Identification = "入库";
            this.Status = InventoryStatus.正常.ToString();
            this.Complete = false;
            this.IsReview = false;
            this.UnitPrice = 0.00M;
            this.TotalPrice = 0.00M;
        }

        /// <summary>
        /// 出库单
        /// </summary>
        /// <param name="EntryId">对应的出库单ID</param>
        public Inventory(string EntryId)
        {
            this.Id = Guid.NewGuid().ToString();
            this.EntryId = EntryId;
            this.InDate = DateTime.Now;
            this.Identification = "出库";
            this.Status = InventoryStatus.正常.ToString();
            this.Complete = false;
            this.IsReview = false;
            this.UnitPrice = 0.00M;
            this.TotalPrice = 0.00M;
        }

        public string Id { get; set; }

        /// <summary>
        /// 自定义的库存单编号。
        /// 如果是配制试剂自动入库，则此处存放 试剂配制记录 Record ID。
        /// </summary>
        public string InventoryNumber { get; set; }

        /// <summary>
        /// 出库时，该出库记录对应的入库记录ID
        /// </summary>
        public string EntryId { get; set; }

        /// <summary>
        /// 物料代码
        /// </summary>
        public string MaterialCode { get; set; }
        
        /// <summary>
        /// 物料名称
        /// </summary>
        public string MaterialName { get; set; }

        /// <summary>
        /// 出/入库数量  对于出库单，这个字段标识领用数量
        /// </summary>
        public decimal EntryQuantity { get; set; }

        /// <summary>
        /// 出/入库数量单位  对于出库单，这个字段标识领用数量单位，对应入库单中可领用数量单位
        /// </summary>
        public string EntryUnit { get; set; }

        /// <summary>
        /// 可领用数量。
        /// 对于入库单，比如进货是5箱，每箱10盒，那么可领用数量就是50盒。
        /// 对于出库单，该字段标识可用消耗的总数量。
        /// 比如：出库单领用两瓶高锰酸钾（每瓶50g），此处则为100g。
        /// </summary>
        public decimal AvailableQuantity { get; set; }

        /// <summary>
        /// 可领用数量单位。
        /// 对于是入库单，此处对应着出库领用数量单位。
        /// 对于是出库单，此处对应着试剂每次消耗的数量单位。
        /// </summary>
        public string AvailableUnit { get; set; }

        /// <summary>
        /// 剩余可领用数量
        /// </summary>
        public decimal ReceivedQuantity { get; set; }

        /// <summary>
        /// 入库时间/出库时间
        /// </summary>
        public DateTime InDate { get; set; }

        /// <summary>
        /// 出库/入库人ID
        /// </summary>
        public string OperatorId { get; set; }

        /// <summary>
        /// 出库/入库人姓名
        /// </summary>
        public string OperatorName { get; set; }

        /// <summary>
        /// 存储位置
        /// </summary>
        public string PositionId { get; set; }

        /// <summary>
        /// 存储条件
        /// </summary>
        public string StorageConditions { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        public string Note { get; set; }

        /// <summary>
        /// 有效期至：比如买来的试剂，会注明有效期限，此处就是填写该时间
        /// </summary>
        public DateTime? Vld { get; set; }

        /// <summary>
        /// 关联的工作流ID
        /// </summary>
        public string WorkFlowId { get; set; }

        /// <summary>
        /// 当前所处工作流中的步骤
        /// </summary>
        public string CurrentWorkFlow { get; set; }

        /// <summary>
        /// 工作流中下一步骤
        /// </summary>
        public string NextWorkFlow { get; set; }

        /// <summary>
        /// 库存单状态，关联枚举
        /// </summary>
        public string Status { get; set; }

        /// <summary>
        /// 库存单标识 入库, 出库
        /// </summary>
        public string Identification { get; set; }

        /// <summary>
        /// 如果有有效期，在有效期前提醒
        /// </summary>
        public int? Remind { get; set; }
        
        /// <summary>
        /// 处置说明/撤销原因
        /// </summary>
        public string DisposalInstructions { get; set; }

        /// <summary>
        /// 该库存单被合并到的库存单ID。
        /// </summary>
        public string MergeTo { get; set; }

        /// <summary>
        /// 合并操作人ID
        /// </summary>
        public string MergePersonId { get; set; }

        /// <summary>
        /// 合并操作人姓名
        /// </summary>
        public string MergePerson { get; set; }

        /// <summary>
        /// 合并操作时间
        /// </summary>
        public DateTime? MergeDate { get; set; }

        /// <summary>
        /// 对于入库单，指示相关出库单是否全部已核销  状态为：核销 该字段为：true ，表示该记录及相关记录都已完成。
        /// 对于出库单，核销时该字段变为 true
        /// </summary>
        public bool Complete { get; set; }
        
        /// <summary>
        /// 核销时间
        /// </summary>
        public DateTime? CancelDate { get; set; }

        /// <summary>
        /// 出库时是否需要审核，如果是将会启动审核流程。该值由物料中的同名属性带入。
        /// </summary>
        public bool IsReview { get; set; }

        /// <summary>
        /// 单价
        /// </summary>
        public decimal UnitPrice { get; set; }

        /// <summary>
        /// 总价
        /// </summary>
        public decimal TotalPrice { get; set; }

        public Inventory GetInstance(string Id)
        {
            var dbContext = new CoreLimsContext();
            return dbContext.Inventory.Where(s => s.Id == Id).FirstOrDefault();
        }

        public void Copy(Inventory other)
        {
            this.InventoryNumber = other.InventoryNumber;
            this.MaterialCode = other.MaterialCode;
            this.MaterialName = other.MaterialName;
            this.EntryQuantity = other.EntryQuantity;
            this.EntryUnit = other.EntryUnit;
            this.AvailableQuantity = other.AvailableQuantity;
            this.AvailableUnit = other.AvailableUnit;
            this.PositionId = other.PositionId.IsNullOrEmpty() ? null : other.PositionId;
            this.StorageConditions = other.StorageConditions.IsNullOrEmpty() ? null : other.StorageConditions;
            this.Vld = other.Vld == null ? null : other.Vld;
            this.Remind = other.Remind;
            this.Note = other.Note.IsNullOrEmpty() ? null : other.Note;
            this.IsReview = other.IsReview;
            this.UnitPrice = other.UnitPrice;
            this.TotalPrice = other.TotalPrice;
        }
    }

    /// <summary>
    /// 库存单扩展信息表
    /// </summary>
    public partial class InventoryEx
    {
        public InventoryEx() {
            this.Id = Guid.NewGuid().ToString();
        }
        public string Id { get; set; }

        /// <summary>
        /// 关联入库单ID
        /// </summary>
        public string InventoryId { get; set; }

        /// <summary>
        /// 规格
        /// </summary>
        public string Specifications { get; set; }

        /// <summary>
        /// 型号
        /// </summary>
        public string Model { get; set; }

        /// <summary>
        /// 供应商ID
        /// </summary>
        public string SupplierId { get; set; }

        /// <summary>
        /// 供应商名称
        /// </summary>
        public string SupplierName { get; set; }

        /// <summary>
        /// 供应商批号
        /// </summary>
        public string SupplierBatchNumber { get; set; }

        /// <summary>
        /// 货号
        /// </summary>
        public string ArticleNumber { get; set; }

    }

    /// <summary>
    /// 出库单领用记录
    /// </summary>
    public partial class UseInventory
    {
        public UseInventory()
        {
            this.Id = Guid.NewGuid().ToString();
            this.UseDateTime = DateTime.Now;
        }

        public string Id { get; set; }

        /// <summary>
        /// 出库单ID
        /// </summary>
        public string OutInventoryId { get; set; }

        /// <summary>
        /// 关联该领用记录的类名
        /// </summary>
        public string DoMainName { get; set; }

        /// <summary>
        /// 关联该领用记录的记录ID
        /// </summary>
        public string DoMainId { get; set; }

        /// <summary>
        /// 物料代码
        /// </summary>
        public string MaterialCode { get; set; }

        /// <summary>
        /// 物料名称
        /// </summary>
        public string MaterialName { get; set; }

        /// <summary>
        /// 领用数量
        /// </summary>
        public decimal? Quantity { get; set; }

        /// <summary>
        /// 数量单位
        /// </summary>
        public string Unit { get; set; }

        /// <summary>
        /// 领用人ID
        /// </summary>
        public string UseId { get; set; }

        /// <summary>
        /// 领用人姓名
        /// </summary>
        public string UseName { get; set; }

        /// <summary>
        /// 领用时间
        /// </summary>
        public DateTime UseDateTime { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        public string Note { get; set; }
    }

}
